// Copyright (c) Microsoft Corporation. All rights reserved.

using System;
using System.Collections.Generic;
using System.Text;

using Microsoft.TeamFoundation.Migration.Toolkit.Wit;

namespace Microsoft.TeamFoundation.Migration.Toolkit.Linking
{
    /// <summary>
    /// Handler for a specific revision of a VC file.
    /// </summary>
    public class TfsRevisionFileHandler: IArtifactHandler
    {
        private ILinkEngine m_engine;                       // Linking engine

        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="engine">Linking engine</param>
        public TfsRevisionFileHandler(
            ILinkEngine engine)
        {
            if (engine == null)
            {
                throw new ArgumentNullException("engine");
            }
            m_engine = engine;
        }

        #region IArtifactHandler Members

        public bool TryFindReflection(
            SystemType sourceSystem, 
            string sourceUri, 
            out string targetId)
        {
            if (string.IsNullOrEmpty(sourceUri))
            {
                throw new ArgumentNullException("sourceUri");
            }
            targetId = null;
            if (IsMyUri(sourceUri))
            {
                if (!(m_engine.VersionControlSession.Source is IVersionControlLinkableEndPoint))
                {
                    TraceManager.TraceWarning("The source system doesn't implement interface IVersionControlLinkableEndPoint. Get revisioned file is not supported");
                    return false;
                }
                
                IVersionControlLinkableEndPoint sourcePoint;
                IVersionControlLinkableEndPoint targetPoint;
                string sourcePath;
                string sourceChangeId;
                bool useSource = (sourceSystem == SystemType.Other);

                if (useSource)
                {
                    targetPoint = m_engine.VersionControlSession.Target;
                    sourcePoint = (IVersionControlLinkableEndPoint)m_engine.VersionControlSession.Source;
                }
                else
                {
                    targetPoint = (IVersionControlLinkableEndPoint)m_engine.VersionControlSession.Source;
                    sourcePoint = m_engine.VersionControlSession.Target;
                }

                sourcePoint.GetPathFromVersionedItem(sourceUri, out sourcePath, out sourceChangeId);
                if ((string.IsNullOrEmpty(sourcePath) || string.IsNullOrEmpty(sourceChangeId)))
                {
                    return true;
                }
                string linkedPath = sourcePoint.FindMappedPath(sourcePath, m_engine.VersionControlSession, useSource);
                string linkedChangeId = TfsUtil.GetChangeIdFromConversionHistory(m_engine.VersionControlSession.Id, sourceChangeId, sourceSystem);
                if (string.IsNullOrEmpty(linkedPath) || string.IsNullOrEmpty(linkedChangeId))
                {
                    return true;
                }
                string revisionedItemArtifact = targetPoint.GetVersionedItemArtifactFromPathAndId(linkedPath, linkedChangeId);
                if (!string.IsNullOrEmpty(revisionedItemArtifact))
                {
                    targetId = revisionedItemArtifact.Substring(LinkingConstants.VcRevisionFilePrefix.Length);
                    return true;
                }
            }
            return false;
        }

        public bool TryTranslateUri(
            string uri, 
            out string id)
        {
            if (string.IsNullOrEmpty(uri))
            {
                throw new ArgumentNullException("uri");
            }

            if (IsMyUri(uri))
            {
                id = uri.Substring(LinkingConstants.VcRevisionFilePrefix.Length);
                return true;
            }
            id = null;
            return false;
        }

        public string CreateUri(
            string id)
        {
            return LinkingConstants.VcRevisionFilePrefix + id;
        }

        #endregion

        /// <summary>
        /// Checks whether URI points to a VC file revision.
        /// </summary>
        /// <param name="uri">URI</param>
        /// <returns>True if URI points to a VC file revision</returns>
        internal static bool IsMyUri(
            string uri)
        {
            return uri.StartsWith(LinkingConstants.VcRevisionFilePrefix, StringComparison.InvariantCulture);
        }
    }
}
